package cn.edu.cqupt.cxcy.util;

import java.lang.reflect.Array;  
import java.lang.reflect.Field;  
import java.lang.reflect.Method;
import java.sql.Time;
import java.text.SimpleDateFormat;  
import java.util.Date;  
import java.util.HashMap;  
import java.util.List;  
import java.util.Map;  
import java.util.Set;

import java.util.Map.Entry;
import java.util.RandomAccess;  
/** 
 * 用来输出JSON字符串，交给Javascript在页面上进行处理。支持JSON对象的嵌套，支持数组 <br/> 
 */
public class JsonUtil {  
	private Map<String, Object> jsonMap = new HashMap<String, Object>();  
	private static SimpleDateFormat formatter = new SimpleDateFormat(  
			"yyyy-MM-dd");  
	public void clear() {  
		jsonMap.clear();  
	}  

	public Map<String, Object> put(String key, Object value) {  
		jsonMap.put(key, value);  
		return jsonMap;  
	}  
	// 判断是否要加引号  
	private static boolean isNoQuote(Object value) {  
		return (value instanceof Integer || value instanceof Boolean  
				|| value instanceof Double || value instanceof Float  
				|| value instanceof Short || value instanceof Long || value instanceof Byte);  
	}  
	private static boolean isQuote(Object value) {  
		return (value instanceof String || value instanceof Character);  
	}  
	@SuppressWarnings("unchecked")  
	@Override  
	/* 
	 * 返回形如{'apple':'red','lemon':'yellow'}的字符串 
	 */  
	public String toString() {  
		StringBuffer sb = new StringBuffer();  
		sb.append("{");  
		Set<Entry<String, Object>> set = jsonMap.entrySet();  

		for (Entry<String, Object> entry : set) {  
			Object value = entry.getValue();  
			if (value == null) {  
				continue;// 对于null值，不进行处理，页面上的js取不到值时也是null  
			}  
			sb.append("'").append(entry.getKey()).append("':");  
			if (value instanceof JsonUtil) {  
				sb.append(value.toString());  
			} else if (isNoQuote(value)) {  
				sb.append(value);  
			} else if (value instanceof Time) {  
				sb.append("'").append((Time)value).append("'");  
			} else if (value instanceof Date) {  
				sb.append("'").append(formatter.format(value)).append("'");  
			} else if (isQuote(value)) {  
				sb.append("'").append(value).append("'");  
			} else if (value.getClass().isArray()) {  
				sb.append(ArrayToStr((int[]) value));  
			} else if (value instanceof Map) {  
				sb.append(fromObject((Map<String, Object>) value).toString());  
			} else if (value instanceof List) {  
				sb.append(list2Str((List<Object>) value));  
			} else {  
				sb.append(toObject(value).toString());  
			}  
			sb.append(",");  
		}  
		int len = sb.length();  
		if (len > 1) {  
			sb.delete(len - 1, len);  
		}  
		sb.append("}");  
		return sb.toString().replace("'", "\"");  
	}  
	
	public static String ArrayToStr(Object array) {  
		if (!array.getClass().isArray())  
			return "[]";  
		StringBuffer sb = new StringBuffer();  
		sb.append("[");  
		int len = Array.getLength(array);  
		Object v = null;  
		for (int i = 0; i < len; i++) {  
			v = Array.get(array, i);  
			if (v instanceof Date) {  
				sb.append("'").append(formatter.format(v)).append("'").append( ",");  
			} else if (isQuote(v)) {  
				sb.append("'").append(v).append("'").append(",");  
			} else if (isNoQuote(v)) {  
				sb.append(i).append(",");  
			} else {  
				sb.append(toObject(v)).append(",");  
			}  
		}  
		len = sb.length();  
		if (len > 1) {
			sb.delete(len - 1, len);  
		}
		sb.append("]");  
		return sb.toString().replace("'", "\"");  
	}  

	@SuppressWarnings("unchecked")
	public static String list2Str(List<Object> list) {
		if (list == null)  
			return null;  
		StringBuffer sb = new StringBuffer();  
		sb.append("["); 
		Object value = null;  
		if(list instanceof RandomAccess) {
			for( int i=0,len=list.size(); i<len; i++) {
				value = list.get(i);
				if (value instanceof Map) {  
					sb.append(toObject((Map<Object, Object>) value).toString()).append(",");  
				} else if (isNoQuote(value)) {  
					sb.append(value).append(",");  
				} else if (isQuote(value)) {  
					sb.append("'").append(value).append("'").append(",");  
				} else if (value instanceof Time) {
					sb.append("'").append(value.toString()).append("'").append(","); 
				} else if (value instanceof List) {
					sb.append("{'list':").append(list2Str((List<Object>) value)).append("},");
				} else {  
					sb.append(toObject(value).toString()).append(",");  
				}
			}
		} else {
			for (java.util.Iterator<Object> it = list.iterator(); it.hasNext();) {  
				value = it.next();  
				if (value instanceof Map) {  
					sb.append(toObject((Map<Object, Object>) value).toString()).append(",");  
				} else if (isNoQuote(value)) {  
					sb.append(value).append(",");  
				} else if (isQuote(value)) {  
					sb.append("'").append(value).append("'").append(",");  
				} else if (value instanceof Time) {
					sb.append("'").append(value.toString()).append("'").append(","); 
				} else if (value instanceof List) {
					sb.append("{'list':").append(list2Str((List<Object>) value)).append("},");
				} else {  
					sb.append(toObject(value).toString()).append(",");  
				}
			}  
		}
		int len = sb.length();  
		if (len > 1) { 
			sb.delete(len - 1, len);  
		}
		sb.append("]");
		return sb.toString().replace("'", "\"");  
	}

	public static JsonUtil toObject(Object bean) {  
		JsonUtil json = new JsonUtil();  
		if (bean == null) {
			return json;  
		}
		Class<? extends Object> cls = bean.getClass();  
		Field[] fs = cls.getDeclaredFields();  //得某个类的所有申明的字段，即包括public、private和proteced，但是不包括父类的申明字段。
		Object value = null;  
		String fieldName = null;  
		Method method = null;  
		int len = fs.length;  
		try {
			for (int i = 0; i < len; i++) {  
				fieldName = fs[i].getName();  //得到属性的字段 如:public int a; 得到a;
				method = cls.getMethod(getGetter(fieldName), (Class[]) null);  
				value = method.invoke(bean, (Object[]) null);  
				json.put(fieldName, value); 
			}  
		} catch (Exception e) {  
			e.printStackTrace();
		}  
		return json;  
	}
	

	public static JsonUtil fromObject(Map<String, Object> map) {  
		JsonUtil json = new JsonUtil();  
		if (map == null)  
			return json;  
		json.getMap().putAll(map);  
		return json;  
	}  
	private static String getGetter(String property) {  
		return "get" + property.substring(0, 1).toUpperCase()  
				+ property.substring(1, property.length());  
	}  
	public Map<String, Object> getMap() {  
		return this.jsonMap;  
	}  
}  
